package cn.oliver.dbindexresearch.controller;

import cn.oliver.dbindexresearch.common.InfoJsonResult;
import cn.oliver.dbindexresearch.common.JsonResult;
import cn.oliver.dbindexresearch.data.dataReader;
import cn.oliver.dbindexresearch.index.BPlusTree;
import cn.oliver.dbindexresearch.index.ExtendibleHash;
import cn.oliver.dbindexresearch.index.LinearHash;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import cn.oliver.dbindexresearch.model.employee;

import java.util.List;

@SuppressWarnings("Duplicates")
@RestController
@RequestMapping(value = "/research1")
class Controller {
    public static void main(String[] args){
        Controller controller = new Controller();
        controller.insertEmployee(100000);
        controller.search(10000);
        controller.searchRange(30000,40000);
        controller.delete(10000);
        controller.insertJobs(10000);
    }

    private static LinearHash linearHash = new LinearHash();
    private static ExtendibleHash extendibleHash = new ExtendibleHash();
    private static BPlusTree bPlusTree = new BPlusTree(100);

    private static List<employee> employeeList = dataReader.loadEmployees();

    public void insertEmployee(int num){
        System.out.println("insert: "+ num);

        long start, end;
        start = System.nanoTime();
        for (int i=0; i<num; i++){
            String key = String.valueOf(employeeList.get(i).id);
            linearHash.insert(key, employeeList.get(i));
        }
        end = System.nanoTime();
        System.out.println("linearHash time:"+(float) Math.log(end - start));

        start = System.nanoTime();
        for (int i=0; i<num; i++){
            String key = String.valueOf(employeeList.get(i).id);
            extendibleHash.insert(key, employeeList.get(i));
        }
        end = System.nanoTime();
        System.out.println("extendibleHash time:"+(float) Math.log(end - start));

        start = System.nanoTime();
        for (int i=0; i<num; i++){
            String key = String.valueOf(employeeList.get(i).id);
            bPlusTree.insert(key, employeeList.get(i));
        }
        end = System.nanoTime();
        System.out.println("bPlusTree time:"+(float) Math.log(end - start));
    }

    public void search(int id) {
        System.out.println("search: " + id);
        String key = String.valueOf(id);
        SearchResult result = new SearchResult();
        long start, end;

        start = System.nanoTime();
        result.linearHashResults.add(linearHash.find(key));
        end = System.nanoTime();
        System.out.println("linearHash time:"+(float) Math.log(end - start));

        start = System.nanoTime();
        result.extensibleHashResults.add(extendibleHash.find(key));
        end = System.nanoTime();
        System.out.println("extendibleHash time:"+(float) Math.log(end - start));

        start = System.nanoTime();
        result.bPlusTreeResults.add(bPlusTree.find(key));
        end = System.nanoTime();
        System.out.println("bPlusTree time:"+(float) Math.log(end - start));

    }



    public void delete( int id){
        System.out.println("delete: " + id);
        String key = String.valueOf(id);
        long start, end;

        start = System.nanoTime();
        linearHash.delete(key);
        end = System.nanoTime();
        System.out.println("linearHash time:"+(float) Math.log(end - start));

        start = System.nanoTime();
        extendibleHash.delete(key);
        end = System.nanoTime();
        System.out.println("extendibleHash time:"+(float) Math.log(end - start));

        start = System.nanoTime();
        bPlusTree.delete(key);
        end = System.nanoTime();
        System.out.println("bPlusTree time:"+(float) Math.log(end - start);
    }

    public void insertJobs(int num){
        System.out.println("insert: "+ num);

        long start, end;
        start = System.nanoTime();
        for (int i=0; i<num; i++){
            String key = String.valueOf(employeeList.get(i).id);
            linearHash.insert(key, employeeList.get(i));
        }
        end = System.nanoTime();
        System.out.println("linearHash time:"+(float) Math.log((end - start)));

        start = System.nanoTime();
        for (int i=0; i<num; i++){
            String key = String.valueOf(employeeList.get(i).id);
            extendibleHash.insert(key, employeeList.get(i));
        }
        end = System.nanoTime();
        System.out.println("extendibleHash time:"+(float) Math.log((end - start)));

        start = System.nanoTime();
        for (int i=0; i<num; i++){
            String key = String.valueOf(employeeList.get(i).id);
            bPlusTree.insert(key, employeeList.get(i));
        }
        end = System.nanoTime();
        System.out.println("bPlusTree time:"+(float) Math.log(end - start));

    }

    public void searchRange(int n1,int n2) {
        System.out.println("searchRange: " +n1+"-"+n2);
        SearchResult result = new SearchResult();
        long start, end;

        start = System.nanoTime();
        for (int i=n1+1; i<n2; i++) {
            String key = String.valueOf(i);
            result.linearHashResults.add(linearHash.find(key));
        }
        end = System.nanoTime();
        System.out.println("linearHash time:" + (float) Math.log(end - start));

        start = System.nanoTime();
        for (int i=n1+1; i<n2; i++) {
            String key = String.valueOf(i);
            result.extensibleHashResults.add(extendibleHash.find(key));
        }
        end = System.nanoTime();
        System.out.println("extendibleHash time:" + (float) Math.log(end - start));

        start = System.nanoTime();
        for (int i=n1+1; i<n2; i++) {
            String key = String.valueOf(i);
            result.bPlusTreeResults.add(bPlusTree.find(key));
        }
        end = System.nanoTime();
        System.out.println("bPlusTree time:" + (float) Math.log(end - start));

    }

    private static class InsertResult{
        public float linearHashTime;
        public float extensibleHashTime;
        public float bPlusTreeTime;
    }

    private static class SearchResult{
        public float linearHashTime;
        public float extensibleHashTime;
        public float bPlusTreeTime;
        public List<Object> linearHashResults;
        public List<Object> extensibleHashResults;
        public List<Object> bPlusTreeResults;
    }

    private static class DeleteResult{
        public float linearHashTime;
        public float extensibleHashTime;
        public float bPlusTreeTime;
    }
}
